package com.contract.management.web;

import java.io.File;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.transaction.Transactional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;
import com.contract.management.bean.ExtraData;
import com.contract.management.bean.ReturnMessage;
import com.contract.management.bean.page.PageBean;
import com.contract.management.bean.page.PageResult;
import com.contract.management.bean.page.QueryBean;
import com.contract.management.bean.page.datatables.DtsPageResult;
import com.contract.management.bean.page.datatables.DtsParams;
import com.contract.management.domain.CommJpaRepository;
import com.contract.management.domain.Contract;
import com.contract.management.domain.User;
import com.contract.management.domain.WorkflowLog;
import com.contract.management.domain.WorkflowNode;
import com.contract.management.service.ContractService;
import com.contract.management.util.ContractUtils;
import com.contract.management.util.StrUtils;
import com.contract.management.util.TmplUtils;
import com.zhuozhengsoft.pageoffice.BorderStyleType;
import com.zhuozhengsoft.pageoffice.FileSaver;
import com.zhuozhengsoft.pageoffice.OpenModeType;
import com.zhuozhengsoft.pageoffice.PageOfficeCtrl;

@Controller
@RequestMapping("/contract")
public class ContractController {
	
	@Value("${office.basepath}")
	private String basePath;
	
	@Autowired
	private CommJpaRepository repo;

	@Autowired
	private ContractService service;
	
	//使用pageoffice控件在WEB中查看合同docx文件
	@RequestMapping("/view/{id}")
	public String view(HttpServletRequest request, HttpSession session, Model model, @PathVariable int id) {
		Map<String, Object> info = repo.queryOne("select new map(c.user.id as useId, c.docName as docName, c.curNode.id as nodeId) from Contract c where c.id = ?0", id);
		if(info == null) {
			model.addAttribute("message", "合同不存在");
			return "show_error_message";
		}
		String docName = (String)info.get("docName");
		int nodeId = (int)info.get("nodeId");
		User user = (User)session.getAttribute("user");
		
//		if(user.getId() != (int)objs[0]) {
//			return "show_error_message";
//		}

		String filePath = basePath + "contracts/"  + docName;
		File file = new File(filePath);
		if(!file.exists()) {
			model.addAttribute("message", "合同文件不存在");
			return "show_error_message";
		}
		String context = request.getContextPath();
		
		PageOfficeCtrl poCtrl = new PageOfficeCtrl(request);
		poCtrl.setAllowCopy(false);	//禁止拷贝
		poCtrl.setServerPage("/poserver.zz");
		poCtrl.setSaveFilePage(context + "/contract/save/pdf");
		poCtrl.addCustomToolButton("下载PDF文件", "SaveAsPDF", 1);
		poCtrl.addCustomToolButton("全屏/还原", "fullScreen", 4);
		poCtrl.addCustomToolButton("隐藏/显示工具栏", "office_toolbar", 0);
		poCtrl.addCustomToolButton("关闭窗口", "close()", 21);
		
		poCtrl.setTitlebar(false);
		poCtrl.setMenubar(false);
		poCtrl.setBorderStyle(BorderStyleType.BorderNone);
		
		poCtrl.webOpen(context + "/contracts/" + docName, OpenModeType.docReadOnly, "");
		model.addAttribute("pageoffice", poCtrl.getHtmlCode("page_office"));
		List<Map<String, Object>> files = repo.query("select new map(id as id, filename as filename, oraName as oraName, type as type) from ContFile  where cont.id = ?0 order by type", id);
		model.addAttribute("files", files);
		model.addAttribute("docName", docName.substring(0, docName.lastIndexOf(".")));
		if(nodeId > 8 && nodeId != 17) {
			poCtrl.setBorderStyle(BorderStyleType.BorderThin);
			return "open_doc_two";	
		} else {
			return "open_doc";
		}
	}
	
	@RequestMapping("/save/pdf")
	public void savePdf(HttpServletRequest req, HttpServletResponse resp) {
		FileSaver fs = new FileSaver(req, resp);
		String filename = fs.getFileName();
		String filePath = basePath + "contracts/"  + filename;
		fs.saveToFile(filePath);
		fs.close();
	}
	
	//使用pageoffice控件在WEB中打印合同
	@RequestMapping("/print/{id}")
	public String print(HttpServletRequest request, HttpSession session, Model model, @PathVariable int id) {
		Object[] objs = repo.queryOne("select c.user.id, c.docName from Contract c where c.id = ?0", id);
		if(objs == null) return "show_error_message";
		
		User user = (User)session.getAttribute("user");
		if(user.getId() != (int)objs[0]) {
			model.addAttribute("message", "您没有打印该合同权限");
			return "show_error_message";
		}

		String filePath = basePath + "contracts/" + (String)objs[1];
		File file = new File(filePath);
		if(!file.exists()) return "show_error_message";
		
		PageOfficeCtrl poCtrl = new PageOfficeCtrl(request);
		poCtrl.setServerPage("/poserver.zz");
		poCtrl.setAllowCopy(false);	//禁止拷贝
		poCtrl.addCustomToolButton("打印设置", "printSet", 0);
		poCtrl.addCustomToolButton("打印", "printFile", 6);
		poCtrl.addCustomToolButton("-", "", 0);
		poCtrl.addCustomToolButton("全屏/还原", "fullScreen", 4);
		poCtrl.addCustomToolButton("隐藏/显示工具栏", "office_toolbar", 0);
//		poCtrl.addCustomToolButton("隐藏/显示标题栏", "title_bar", 0);
		poCtrl.addCustomToolButton("关闭窗口", "close()", 21);
		
		poCtrl.setTitlebar(false);
		poCtrl.setMenubar(false);
//		poCtrl.setOfficeToolbars(false);
//		poCtrl.setCustomToolbar(false);
		poCtrl.setBorderStyle(BorderStyleType.BorderNone);
		String context = request.getContextPath();
		poCtrl.webOpen(context + "/contracts/" + (String)objs[1], OpenModeType.docReadOnly, "");
		model.addAttribute("pageoffice", poCtrl.getHtmlCode("page_office"));
		return "open_doc";
	}
	
	
	@RequestMapping("/openDoc")
	public String openDoc(HttpServletRequest request, Model model) {
		PageOfficeCtrl poCtrl = new PageOfficeCtrl(request);
		poCtrl.setServerPage("/poserver.zz");
		poCtrl.setAllowCopy(false);	//禁止拷贝
		poCtrl.addCustomToolButton("打印设置", "printSet", 0);
		poCtrl.addCustomToolButton("打印", "printFile", 6);
		poCtrl.addCustomToolButton("-", "", 0);
//		poCtrl.addCustomToolButton("全屏/还原", "fullScreen", 4);
		poCtrl.addCustomToolButton("隐藏/显示工具栏", "office_toolbar", 0);
//		poCtrl.addCustomToolButton("隐藏/显示标题栏", "title_bar", 0);
		poCtrl.addCustomToolButton("关闭窗口", "close()", 21);
		
//		poCtrl.setTitlebar(false);
		poCtrl.setMenubar(false);
//		poCtrl.setOfficeToolbars(false);
//		poCtrl.setCustomToolbar(false);
		poCtrl.setBorderStyle(BorderStyleType.BorderNone);
		poCtrl.webOpen("/templates/test.docx", OpenModeType.docReadOnly, "");
		model.addAttribute("pageoffice", poCtrl.getHtmlCode("page_office"));
		return "open_doc";
	}
	
	@RequestMapping("/list")
	@ResponseBody
	public DtsPageResult list(HttpSession session, DtsParams params) {
		User user = (User)session.getAttribute("user");
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		String[] cols = new String[]{"id", "no", "company.name", "area", "contSmallClass.name", "ycfq", "isHjb", "jfWtr", "jfLxr", "fyhj", "nodeInfo", "user.name", "createTime"};
		PageBean pb = params.createQuery(cols, "Contract", (query) -> {
			List<QueryBean> ret = new ArrayList<>();
			for(Map.Entry<String, String> entry : query.entrySet()) {
				if(StrUtils.isEmpty(entry.getValue())) continue;
				String key = entry.getKey();
				if("status".equals(key)) {
					int status = Integer.valueOf(entry.getValue());
					if(status == 1) {	//已完成合同
						ret.add(new QueryBean("status", "=", status));	
					} else if(status == -2) { //作废盖章合同
						ret.add(new QueryBean("status", "=", -1));
						ret.add(new QueryBean("curNode.id", "=", 17));
					} else if(status == 7) { //已盖章中合同
						ret.add(new QueryBean("status", "<>", -1));
						ret.add(new QueryBean("curNode.id", ">", 7));
					} else if(status == 6) { //未盖章合同
						ret.add(new QueryBean("status", "<>", -1));
						ret.add(new QueryBean("curNode.id", "<=", 7));
					}
					 
				} else if("no".equals(key)) {
					ret.add(new QueryBean("no", "like", "%" + entry.getValue() + "%"));
				} else if("jfWtr".equals(key)) {
					ret.add(new QueryBean("jfWtr", "like", "%" + entry.getValue() + "%"));
				} else if("jfLxr".equals(key)) {
					ret.add(new QueryBean("jfLxr", "like", "%" + entry.getValue() + "%"));
				} else if("start_date".equals(key)) {
					try {
						ret.add(new QueryBean("createTime", ">=", df.parse(entry.getValue()), "start_date"));
					} catch (ParseException e) {
						e.printStackTrace();
					}
				} else if("end_date".equals(key)) {
					try {
						ret.add(new QueryBean("createTime", "<=", df.parse(entry.getValue()), "end_date"));
					} catch (ParseException e) {
						e.printStackTrace();
					}
				} else if("user".equals(key)) {
					ret.add(new QueryBean("user.name", "like", "%" + entry.getValue() + "%"));
				} else if("company".equals(key)) {
					String company = entry.getValue();
					if("B".equals(company)) {
						ret.add(new QueryBean("area", "=", company));	
					} else {
						ret.add(new QueryBean("area", "=", "A"));
						ret.add(new QueryBean("company.code", "=", company));
					}
					
				} else if("ywlx".equals(key)) {
					ret.add(new QueryBean("contSmallClass.id", "=", Integer.valueOf(entry.getValue())));
				}
			}
			if(user.getRight() == 5) {
				ret.add(new QueryBean("user.id", "=", user.getId()));
			}
			return ret;
		});
		PageResult pr = repo.query(pb, params.getStart(), params.getLength());
		return new DtsPageResult(params.getDraw(), pr.getTotalCount(), pr.getData());
	}
	
	@RequestMapping("/edit/{id}")
	public String edit(HttpServletRequest request, HttpSession session, Model model, @PathVariable int id) {
		User user = (User)session.getAttribute("user");
		Contract ct = repo.find(Contract.class, id);
		if(ct == null) {
			model.addAttribute("message", "该合同不存在");
			return "show_error_message";
		}
		if(ct.getUser().getId() != (int)user.getId()) {
			model.addAttribute("message", "您没有修改该合同权限");
			return "show_error_message";
		}
		if(ct.getCurNode().getId() != 1 && ct.getCurNode().getId() != 2 && ct.getCurNode().getId() != 8) {
			model.addAttribute("message", "合同禁止修改");
			return "show_error_message";
		}
		ct.setData(JSON.parseObject(ct.getExtraData(), ExtraData.class));
		ct.setSbItems(repo.query("from SbItems where ct = ?0", ct));

		//正常报价
		List<Object[]> zcbjs = repo.query("select bjje, concat('[', bjje, ']', smallType) from Bjd where ywlx = ?0", ct.getYwlx());
		if(zcbjs.size() == 0) {
			zcbjs.add(new Object[]{0, "无报价信息"});
		}
		model.addAttribute("zcbjs", zcbjs);
		
		if("DS".equals(ct.getYwlx()) && (ct.getSbItems() == null || ct.getSbItems().size() == 0)) {
			ct.setSbItems(service.createDsItems());
		}

				
		model.addAttribute("temp_info", ContractUtils.getSeleTemp(ct));
		model.addAttribute("temp_id", service.getTemplateId(ct));
		model.addAttribute("contract", ct);
		model.addAttribute("form_action", "contract/edit/save");
		return "contract_edit";
	}
	
	@RequestMapping("/edit/save")
	public String saveEdit(HttpSession session, Contract ct, Model model) {
		User user = (User)session.getAttribute("user");

		Contract oldCt = repo.find(Contract.class, ct.getId());
		if(oldCt == null) {
			model.addAttribute("text", "该合同不存在");
			return "show_error_message";
		}
		if(oldCt.getUser().getId() != (int)user.getId()) {
			model.addAttribute("text", "您没有修改该合同权限");
			return "show_error_message";
		}
		
		ct.setExtraData(JSON.toJSONString(ct.getData()));
		
		ct.setCompany(repo.queryOne("from Config where id = ?0 and type='COMPANY'", ct.getCompany().getId()));
		ct.setYwlx(oldCt.getYwlx());
		ct.setYcfq(oldCt.getYcfq());
		ct.setContSmallClass(oldCt.getContSmallClass());
		ct.setCreateTime(oldCt.getCreateTime());
		ct.setNo(oldCt.getNo());
		ct.setType(oldCt.getType());
		ct.setCurNode(oldCt.getCurNode());
		
		ct.setAccount(oldCt.getAccount());
		ct.setBank(oldCt.getBank());
		ct.setBankNumber(oldCt.getBankNumber());
		
		ct.setUser(user);
		if(ct.getType() == 1) {
			//保存合同
			WorkflowNode nextNode = service.updateContract(ct);
			model.addAttribute("ct", ct);
			model.addAttribute("message", nextNode.getDesc());
			return "contract_edit_save";
			
		} else {
			ct.setNextOper(oldCt.getNextOper());
			ct.setNodeInfo(oldCt.getNodeInfo());
			ct.setAudit(oldCt.getAudit());
			ct.setStatus(oldCt.getStatus());
			service.updateBlankContract(ct);
			return "redirect:/apply/put/list";
		}
	}

	
	@RequestMapping(value = "/loginfo", method = RequestMethod.POST)
	@ResponseBody
	public ReturnMessage loginfo(int id) {
		List<Object[]> ret = repo.query("select l.user.name, l.spsm, l.memo, l.createTime, l.spPic from WorkflowLog l where l.ct.id = ?0 order by l.id desc", id);
		List<Map<String, Object>> data = new ArrayList<>();
		for (Object[] objs : ret) {
			Map<String, Object> map = new HashMap<>();
			map.put("name", objs[0]);
			map.put("spsm", objs[1]);
			map.put("memo", objs[2]);
			map.put("createTime", objs[3]);
			map.put("spPic", objs[4]);
			data.add(map);
		}
		Map<String, Object> map = new HashMap<>();
		map.put("data", data);
		
		Object[] objs = repo.queryOne("select audit.name, curNode.id from Contract where id = ?0", id);
		if(objs != null && (Integer)objs[1] != 13 && (Integer)objs[1] != 17) {
			map.put("nextOper", (String)objs[0]);
		}
		
		String html = TmplUtils.parseHtml("log_item", map);
		return new ReturnMessage(true, html);
	}
	
	@RequestMapping(value = "/big/class", method = RequestMethod.POST)
	@ResponseBody
	public List<Object[]> getContBigClass(String area) {
		return repo.query("select id, name from ContBigClass where area = ?0", area);
	}
	
	@RequestMapping(value = "/small/class", method = RequestMethod.POST)
	@ResponseBody
	public List<Object[]> getContSmallClass(int id) {
		return repo.query("select CONCAT(id, '_', hasYcfq, '_', hasHjb) as id, name from ContSmallClass where bigClass.id = ?0", id);
	}
	
	
	
	/**
	 * 删除合同文件
	 * 
	 * @param session
	 * @param key		文件ID
	 * @return
	 */
	@RequestMapping(value = "/file/del", method = RequestMethod.POST)
	@ResponseBody
    public Map<String, String> delFile(HttpSession session, int key) {
		User user = (User)session.getAttribute("user");
		
		Map<String, String> ret = new HashMap<>();
		Map file = repo.queryOne("select new map(c.id as id, c.cont.user.id as userId, c.filename as filename) from ContFile c where c.id = ?0", key);
		if(file == null) {
//			ret.put("error", "该文件不存在");
//			return ret;
			return ret;
		}

		
		if((int)file.get("userId") !=  user.getId()) {
			ret.put("error", "您没有删除该文件权限");
			return ret;
		}
		
		File f = new File(basePath + "uploads", file.get("filename").toString());
		if(f.exists()) {
			//此处先不删除原文件，表单提交时在做处理
//			f.delete();
		} else {
//			ret.put("error", "该文件不存在");
			return ret;
		}
		
		return ret;
	}
	
	@RequestMapping("/cancel")
	@ResponseBody
	@Transactional
    public ReturnMessage cancel(HttpSession session, int id) {
		User user = (User)session.getAttribute("user");
		Map<String, Object> ret = repo.queryOne("select new map(c.user.id as userId, c.curNode.id as nodeId) from Contract c where c.id = ?0", id);
		if((int)ret.get("userId") !=  user.getId()) {
			return new ReturnMessage(false, "您没有作废该合同权限");
		}
		if((int)ret.get("nodeId") != 8) {
			return new ReturnMessage(false, "该合同不能被作废");
		}
		WorkflowNode nextNode = repo.find(WorkflowNode.class, 17);
		repo.queryUpdate("update Contract set curNode = ?0, nodeInfo = ?1, status = -1 where id = ?2", nextNode, nextNode.getName(), id);
		
		WorkflowLog log = new WorkflowLog();
		log.setCt(new Contract(id));
		log.setUser(user);
		log.setSpjg(1);
		log.setSpsm(nextNode.getName());
		log.setCreateTime(new Date());
		repo.persist(log);
		return new ReturnMessage(true);
	}
}
